iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
Mobile Development

我將點燃Swiftの大海系列 第 19

Day19. Swift一定要會の留言板實作篇 (4)

  • 分享至 

  • xImage
  •  

到目前為止我們完成了留言板該有的功能:

  • 送出留言資料
  • 顯示使用者、留言內容、留言時間
  • 依照時間做排序(舊到新/新到舊)

接下來我們今天來多做一些 tableView 的進階運用喔!

左滑刪除

func - deleteMessage

我們要先來設定 deleteMessage 的 func !
我們需要將該行訊息從資料庫以及陣列中刪掉
不過為了避免使用者誤觸所以會跳出警告訊息讓使用者確認是否刪除喔!

    func deleteMessage(_ message: MessageBoard, 
                       at indexPath: IndexPath) {

        // 彈出一個警告視窗,詢問使用者是否要確認刪除
        let alertController = UIAlertController(title: "刪除", 
                                                message: "確定刪除嗎",                                                   
                                                preferredStyle: .alert)

        // 設定確定要刪除的 Action
        let deleteAction = UIAlertAction(title: "確定", 
                                         style: .default) {
            [weak self] _ in
            
            // 初始化 Realm 
            let realm = try! Realm()

            // 在 Realm 中刪除該訊息
            try! realm.write {
                realm.delete(message)
            }

            // 從陣列中移除該訊息,並更新表格
            self?.messageArray.remove(at: indexPath.row)
            self?.tbvTest.deleteRows(at: [indexPath], with: .fade)
        }

        // 定義一個取消動作,取消操作不做任何變更
        let cancelAction = UIAlertAction(title: "取消", 
                                         style: .cancel,
                                         handler: nil)

        // 將確定和取消的動作加入到警告視窗中
        alertController.addAction(deleteAction)
        alertController.addAction(cancelAction)

        // 顯示警告視窗
        present(alertController, animated: true, completion: nil)
    }

trailingSwipeActionConfigurationForRowAt

接下來做設定 SwipeActionsConfigurationForRowAt 這是用來設定 tableViewCell 的滑動!

  • trailing 是左滑
  • leading 是右滑
    func tableView(_ tableView: UITableView, 
                   trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        ...
    }

在 func 內部的程式碼就要來設定刪除的動作啦!
我們除了使用前面設定的 deleteMessage 的刪除選項外
新增一個當使用者完全滑動後也能直接刪掉的動作

        // 定義一個刪除的動作,當使用者左滑時會顯示 "刪除" 選項
        let deleteAction = UIContextualAction(style: .destructive, 
                                              title: "刪除") { 
            [weak self] (_, _, completionHandler) in

            // 使用 weak self 防止循環引用
            guard let self = self else { return }

            // 根據當前滑動的列,獲取對應的訊息
            let message = self.messageArray[indexPath.row]

            // 刪除該訊息並更新表格
            self.deleteMessage(message, at: indexPath)

            // 操作完成後,告訴系統這個動作已經處理完畢
            completionHandler(true)
        }
        // 設定刪除動作的背景顏色為紅色
        deleteAction.backgroundColor = .red

        // 將刪除動作加入配置中
        let configuration = UISwipeActionsConfiguration(actions: [deleteAction])

        // 設定當使用者完全滑動時,自動執行第一個動作(刪除)
        configuration.performsFirstActionWithFullSwipe = true
        return configuration

右滑編輯

func - editMessage

接下來先來設定 editMessage 的 func !
我們需要將該行訊息從資料庫以及陣列中做編輯
一樣要跳出警告訊息讓使用者確認是否要編輯喔!

    func editMessage(_ message: MessageBoard, 
                     at indexPath: IndexPath) {
        // 彈出一個警告視窗,讓使用者可以編輯訊息內容
        let alertController = UIAlertController(title: "編輯", 
                                                message: nil, 
                                                preferredStyle: .alert)

        // 在警告視窗中加入一個文字輸入框,並將訊息的當前內容顯示在輸入框中
        alertController.addTextField { textField in
            textField.text = message.content
        }

        // 定義一個保存動作
        let saveAction = UIAlertAction(title: "保存", 
                                       style: .default) { 
            [weak self] _ in
            // 確認新的內容不為空,並從輸入框中取得新的內容
            guard let newContent = alertController.textFields?.first?.text, !newContent.isEmpty else { return }

            // 初始化 Realm 資料庫
            let realm = try! Realm()

            // 在 Realm 中寫入變更,更新訊息的內容和當前時間
            try! realm.write {
                message.content = newContent
                message.currentTime = self?.getSystemTime() ?? ""
            }

            // 更新表格中的當前列,讓新的內容顯示出來
            self?.tbvTest.reloadRows(at: [indexPath], 
                                     with: .automatic)

            // 將訊息重新排序並重新載入表格
            self?.sortMessages()
            self?.tbvTest.reloadData()
        }

        // 一樣要定義一個取消動作,取消操作不做任何變更
        let cancelAction = UIAlertAction(title: "取消", 
                                         style: .cancel, 
                                         handler: nil)

        alertController.addAction(saveAction)
        alertController.addAction(cancelAction)

        present(alertController, animated: true, completion: nil)
    }

trailingSwipeActionConfigurationForRowAt

   func tableView(_ tableView: UITableView, 
                   leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        ...
    

在 func 內部的程式碼我們一樣要來設定編輯的動作
我們除了使用前面設定的 editMessage 的刪除選項外
新增一個當使用者完全滑動後也能直接編輯的動作
基本上的操作都是一樣的所以要重複練習喔!

        let editAction = UIContextualAction(style: .normal,
                                            title: "編輯") {
            [weak self] (_, _, completionHandler) in
            
            guard let self = self else { return }
            
            let message = self.messageArray[indexPath.row]
            
            // 編輯該訊息並更新表格
            self.editMessage(message, at: indexPath)
            
            // 操作完成後,告訴系統這個動作已經處理完畢
            completionHandler(true)
        }
        // 設定編輯動作的背景顏色為藍色
        editAction.backgroundColor = .blue

        // 將編輯動作加入配置中
        let configuration = UISwipeActionsConfiguration(actions: [editAction])
            
        // 設定當使用者完全滑動時,自動執行第一個動作(編輯)
        configuration.performsFirstActionWithFullSwipe = true
        return configuration

結論

現在大家都學會了進階用法了吧!明天我們來復刻 ios 的鬧鐘!


上一篇
Day18. Swift一定要會の留言板實作篇 (3)
下一篇
Day20. Swift一定要會のios鬧鐘復刻實作篇 (1)
系列文
我將點燃Swiftの大海21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言